#include "keyboard_win32.h"
#include "keyboard.h"

#include "application/game_application.h"

#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#include <cassert>

using namespace input;

/// This implementation is specific to Win32. Move it to another lib?
#ifdef _PLATFORM_WIN32

////////////////////////////////////////////////////////////////
// win32 implementations for Keyboard functions
bool	Keyboard::IsNumLockOn()	{		return (GetKeyState(VK_NUMLOCK) & 0x0001);	}
bool	Keyboard::IsCtrlDown()	{		return (GetKeyState(VK_LCONTROL) & 0x8000) || (GetKeyState(VK_RCONTROL) & 0x8000);	}
bool	Keyboard::IsShiftDown()	{		return (GetKeyState(VK_LSHIFT) & 0x8000) || (GetKeyState(VK_RSHIFT) & 0x8000);	}
bool	Keyboard::IsAltDown()	{		return (GetKeyState(VK_LMENU) & 0x8000) || (GetKeyState(VK_RMENU) & 0x8000);	}
bool	Keyboard::IsVKDown(unsigned int VK)	{	return (GetKeyState(VK) & 0x8000) > 0;	}

bool Keyboard::GetClipBoard(std::string& Buffer)
{
	if ( OpenClipboard(NULL) ) 
	{
		if (IsClipboardFormatAvailable(CF_TEXT) ||
			IsClipboardFormatAvailable(CF_OEMTEXT))
		{
			HANDLE hData = GetClipboardData( CF_OEMTEXT );
			if (hData)
			{
				char * buffer = (char*)GlobalLock( hData );
				if (buffer)
					Buffer = buffer;
				GlobalUnlock( hData );
			} else
			{
				DWORD error = GetLastError();
				// probably thread isn't ready for clipboard yet
			//	_LOG(MSG_WARNING, "Error retrieving clipboard info: " << error);
			}
		}
		CloseClipboard();
		return !Buffer.empty();
	}
	return false;
}


bool Keyboard::SetClipBoard(std::string& Buffer)
{
	if ( OpenClipboard(NULL) ) 
	{
		//if (EmptyClipboard())
		{
			int size = sizeof(char) * (Buffer.size()+1);
			HGLOBAL	Handle = GlobalAlloc(GMEM_MOVEABLE, size); 
			if (Handle == NULL) 
			{ 
				CloseClipboard(); 
				return FALSE; 
			} 
	 
			// Lock the handle and copy the text to the buffer. 
	 
			void*	pData = GlobalLock(Handle); 
			memset(pData, 0, size);
			memcpy(pData, Buffer.c_str(), Buffer.size());
			GlobalUnlock(Handle); 
 
			SetClipboardData( CF_TEXT, Handle );
		}
		CloseClipboard();
		return true;
	}
	return false;
}

bool Keyboard::SetClipBoard(std::wstring& Buffer)
{
	if ( OpenClipboard( NULL) ) 
	{
		BOOL Res = EmptyClipboard(); 
		{
			int size = sizeof(unsigned short) * (Buffer.size()+1);
			HGLOBAL	Handle = GlobalAlloc(GMEM_MOVEABLE, size); 
			if (Handle == NULL) 
			{ 
				CloseClipboard(); 
				return FALSE; 
			} 
	 
			// Lock the handle and copy the text to the buffer. 
	 
			void*	pData = GlobalLock(Handle); 
			memset(pData, 0, size);
			memcpy(pData, Buffer.c_str(), size - sizeof(unsigned short));
			GlobalUnlock(Handle); 
 
			HANDLE hRes = SetClipboardData( CF_UNICODETEXT, Handle );
		}
		CloseClipboard();
		return true;
	}
	return false;
}
#endif // _PLATFORM_WIN32
